package com.juntuo.util;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.ScriptPreProcessor;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.*;
import com.juntuo.Enums.CertStatus;
import com.juntuo.Enums.InstitutionStatus;
import com.juntuo.entity.vo.CertResult;

import javax.net.ssl.*;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CertificateUtils {


    private static CertResult vdeSearch(WebClient webClient, String certNo){
        webClient.getOptions().setJavaScriptEnabled(true);
        new InterceptWebConnection(webClient);
        CertResult map = new CertResult();
        map.setCertNo(certNo);
        HtmlPage page = null;
        try {
            page = webClient.getPage("https://www2.vde.com/en/institute/onlineservice/vde-approved-products/pages/online-search.aspx");//尝试加载上面图片例子给出的网页
            HtmlInput input=page.querySelector(".zertreg-search-txtinput");
            input.setValueAttribute(certNo);
            HtmlSubmitInput button = page.querySelector(".zertreg-search-btnsearch");
            HtmlPage nextPage = button.click();
            String result = nextPage.asXml();
            if(result.contains("No search results.")){
                System.out.println(CertStatus.MISSING.getCode());
                map.setResult(CertStatus.MISSING.getCode());
                return map;
            }else if(result.contains("Results for")){
                map.setResult(CertStatus.OK.getCode());
                System.out.println(CertStatus.OK.getCode());
                List<Object> rows = nextPage.getByXPath("//tr[@title='Details']");
                for(Object row0:rows){
                    HtmlTableRow row = (HtmlTableRow) row0;
                    if(certNo.equals(row.getCell(0).getTextContent())){
                        map.setCompanyName(row.getCell(1).getTextContent());
                        map.setProduct(row.getCell(2).getTextContent());
                        map.setModel(row.getCell(3).getTextContent());
                    }
                }

                return map;
            }else {
                map.setResult(CertStatus.NEED_CHANGE_LOGIC.getCode());
                System.out.println(CertStatus.NEED_CHANGE_LOGIC.getCode());
                return map;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        map.setResult(CertStatus.BAD_NET.getCode());
        System.out.println(CertStatus.BAD_NET.getCode());
        return map;
    }
    private static CertResult tuvRheinlandSearch(WebClient webClient,String certNo){
        webClient.getOptions().setJavaScriptEnabled(false);
        CertResult map = new CertResult();
        map.setCertNo(certNo);
        HtmlPage page = null;
        try {
            String url = "https://www.certipedia.com/certificates/{certNo}?locale=en";
            url=url.replace("{certNo}",certNo);
            System.out.println(url);
            page = webClient.getPage(url);//尝试加载上面图片例子给出的网页
//            webClient.waitForBackgroundJavaScript(10000);//异步JS执行需要耗时,所以这里线程要阻塞30秒,等待异步JS执行结束
            String result = page.asXml();
            if(result.contains("Invalid Certificate") || result.contains("No Certificate with number")){
                System.out.println(CertStatus.MISSING.getCode());
                map.setResult(CertStatus.MISSING.getCode());
                return map;
            }else if(result.contains("Certificate Holder") || result.contains("Certificate Number")){
                System.out.println(CertStatus.OK.getCode());
                map.setResult(CertStatus.OK.getCode());
                HtmlTableBody tableBody=page.querySelector("tbody");
                List<HtmlTableRow> rows=tableBody.getRows();
                for(int i=0;i<rows.size();i++){
                    HtmlTableRow row = rows.get(i);
                    HtmlTableCell title=row.getCell(0);
                    if("Certificate Holder:".equals(title.getFirstChild().getTextContent().trim())){
                        HtmlTableCell content=row.getCell(1);
                        String conXml=content.asXml();
                        int start=conXml.indexOf("<strong>");
                        int end=conXml.indexOf("</strong>");
                        map.setCompanyName(conXml.substring(start+8,end).trim());
                        continue;
                    }
                    if("Certified Product:".equals(title.getFirstChild().getTextContent().trim())){
                        HtmlTableCell content=row.getCell(1);
                        String conXml=content.asXml();
                        map.setProduct(conXml.substring(0,conXml.indexOf("<div")).replace("<td>","").trim());
                        int start=conXml.indexOf("Model Designation:");
                        int end=conXml.indexOf("</p>");
                        String models = conXml.substring(start+18,end).replace("<br/>"," ").replace("\r","").replace("\n","").trim();
                        if(models.length()>20){
                            models= models.substring(0,20)+"...";
                        }
                        map.setModel(models);
                        continue;
                    }
                }

                return map;
            }else {
                System.out.println(CertStatus.NEED_CHANGE_LOGIC.getCode());
                map.setResult(CertStatus.NEED_CHANGE_LOGIC.getCode());
                return map;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(CertStatus.BAD_NET.getCode());
        map.setResult(CertStatus.BAD_NET.getCode());
        return map;
    }

    /**
     * SAA查询不到工厂名称
     * @param webClient
     * @param certNo
     * @return
     */
    private static CertResult saaSearch(WebClient webClient,String certNo){
        webClient.getOptions().setJavaScriptEnabled(false);
        CertResult map = new CertResult();
        map.setCertNo(certNo);
        HtmlPage page = null;
        try {
            String url = "http://www.saaapprovals.com.au/client/index.php?approval_number={certNo}&description=&model=";
            url=url.replace("{certNo}",certNo);
            System.out.println(url);
            page = webClient.getPage(url);//尝试加载上面图片例子给出的网页
//            webClient.waitForBackgroundJavaScript(10000);//异步JS执行需要耗时,所以这里线程要阻塞30秒,等待异步JS执行结束
            String result = page.asXml();
            if(result.contains("No Results Found.")){
                System.out.println(CertStatus.MISSING.getCode());
                map.setResult(CertStatus.MISSING.getCode());
                return map;
            }
            List<Object> cells = page.getByXPath("//td[@data-label='Expiry Date']");
            if(cells==null){
                System.out.println(CertStatus.NEED_CHANGE_LOGIC.getCode());
                map.setResult(CertStatus.NEED_CHANGE_LOGIC.getCode());
                return map;
            }
            HtmlTableCell cell = (HtmlTableCell) cells.get(0);
            String dateStr = cell.getTextContent();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date expiryDate = sdf.parse(dateStr);
            if(expiryDate.getTime()-new Date().getTime()>0){
                System.out.println(CertStatus.OK.getCode());
                map.setResult(CertStatus.OK.getCode());
                return map;
            }else{
                System.out.println(CertStatus.MISSING.getCode());
                map.setResult(CertStatus.MISSING.getCode());
                return map;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(CertStatus.BAD_NET.getCode());
        map.setResult(CertStatus.BAD_NET.getCode());
        return map;
    }

    /**
     * 南德零部件较少 暂时不做更新名称等
     * @param webClient
     * @param certNo
     * @return
     */
    private static CertResult tuvsudSearch(WebClient webClient,String certNo){
        webClient.getOptions().setJavaScriptEnabled(false);
        CertResult map = new CertResult();
        map.setCertNo(certNo);
        HtmlPage page = null;
        try {
            String url = "https://certificateexplorer2.tuev-sued.de/web/ig-tuvs/certificate?lang=en&q={certNo}";
            url=url.replace("{certNo}",certNo);
            System.out.println(url);
            page = webClient.getPage(url);//尝试加载上面图片例子给出的网页
//            webClient.waitForBackgroundJavaScript(10000);//异步JS执行需要耗时,所以这里线程要阻塞30秒,等待异步JS执行结束
            String result = page.asXml();

            if(result.contains("We are sorry")){
                System.out.println(CertStatus.MISSING.getCode());
                map.setResult(CertStatus.MISSING.getCode());
                return map;
            }else if(result.contains("Certificate holder")){
                System.out.println(CertStatus.OK.getCode());
                map.setResult(CertStatus.OK.getCode());
                return map;
            }else{
                System.out.println(CertStatus.NEED_CHANGE_LOGIC.getCode());
                map.setResult(CertStatus.NEED_CHANGE_LOGIC.getCode());
                return map;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(CertStatus.BAD_NET.getCode());
        map.setResult(CertStatus.BAD_NET.getCode());
        return map;
    }
    private static CertResult ulSearch(WebClient webClient,String certNo){
        certNo=certNo.toLowerCase();
        CertResult map = new CertResult();
        map.setCertNo(certNo);
        webClient.getOptions().setJavaScriptEnabled(true);
        HtmlPage page = null;
        try {
            String url = "http://database.ul.com/cgi-bin/XYV/cgifind.new/LISEXT/1FRAME/index.html";
            page = webClient.getPage(url);
            HtmlInput input=page.querySelector("[name=Filenbr]");
            input.setValueAttribute(certNo);
            HtmlSubmitInput button = page.querySelector("[type=SUBMIT]");
            HtmlPage nextPage = button.click();
            String result = nextPage.asXml();
            if(result.contains("Sorry, No Match Found")){
                System.out.println(CertStatus.MISSING.getCode());
                map.setResult(CertStatus.MISSING.getCode());
                return map;
            }else if(result.contains("Link to File") && result.contains("Refine Your Search")){
                System.out.println(CertStatus.OK.getCode());


                HtmlTableBody tableBody = nextPage.querySelector("tbody");
                List<HtmlTableRow> rows = tableBody.getRows();
                HtmlTableRow row= rows.get(2);
                map.setResult(CertStatus.OK.getCode());
                map.setCompanyName(row.getCell(0).getTextContent().trim());
                map.setProduct(row.getCell(1).getTextContent().trim());
                return map;
            }else {
                System.out.println(CertStatus.NEED_CHANGE_LOGIC.getCode());
                map.setResult(CertStatus.NEED_CHANGE_LOGIC.getCode());
                return map;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(CertStatus.BAD_NET.getCode());
        map.setResult(CertStatus.BAD_NET.getCode());
        return map;
    }
    public static CertResult dekraKemaSearch(WebClient webClient,String certNo){
        webClient.getOptions().setUseInsecureSSL(true);
        webClient.getOptions().setJavaScriptEnabled(true);
        webClient.getOptions().setJavaScriptEnabled(true);
        CertResult map = new CertResult();
        map.setCertNo(certNo);
        HtmlPage page = null;
        try {
            String url = "https://content.infomantis.de/impf/?app=dekra-certifiedProducts&PHPSESSID=&view=form&search=certificateNumber";
            page = webClient.getPage(url);
//            webClient.waitForBackgroundJavaScript(180000);//异步JS执行需要耗时,所以这里线程要阻塞30秒,等待异步JS执行结束
            HtmlInput firstname=(HtmlInput)page.getElementById("firstname");
            firstname.setValueAttribute("qqq");
            HtmlInput lastname=page.querySelector("#lastname");
            lastname.setValueAttribute("qqq");
            HtmlInput phone=page.querySelector("#phone");
            phone.setValueAttribute("133456788");
            HtmlInput email=page.querySelector("#email");
            email.setValueAttribute("3313971898@qq.com");
            HtmlTextArea reason=page.querySelector("#reason");
            reason.setText("check valid");
            HtmlInput cert=page.querySelector("#subForm-certificatenumber");
            cert.setValueAttribute(certNo);


            HtmlSubmitInput button = page.querySelector("#search");
            HtmlPage nextPage = button.click();
            String result = nextPage.asXml();

            if(result.contains("matched no certificates")){
                System.out.println(CertStatus.MISSING.getCode());
                map.setResult(CertStatus.MISSING.getCode());
                return map;
            }else  if(result.contains("Certificate Number") && result.contains("Certificate type")){
                System.out.println(CertStatus.OK.getCode());
                map.setResult(CertStatus.OK.getCode());
                HtmlTableBody tableBody = nextPage.querySelector("tbody");
                List<HtmlTableRow> rows = tableBody.getRows();
                for(HtmlTableRow row:rows){
                    HtmlTableCell title=row.getCell(0);
                    if("Manufacturer".equals(title.getTextContent())){
                        map.setCompanyName(row.getCell(1).getTextContent().trim());
                        continue;
                    }
                    if("Certified product".equals(title.getTextContent())){
                        map.setProduct(row.getCell(1).getTextContent().trim());
                        continue;
                    }
                    if("Type Number".equals(title.getTextContent())){
                        map.setModel(row.getCell(1).getTextContent().trim());
                        continue;
                    }
                }
                return map;
            }else {
                System.out.println(CertStatus.NEED_CHANGE_LOGIC.getCode());
                map.setResult(CertStatus.NEED_CHANGE_LOGIC.getCode());
                return map;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(CertStatus.BAD_NET.getCode());
        map.setResult(CertStatus.BAD_NET.getCode());
        return map;
    }







    public static CertResult searchByCode(WebClient webClient,String certNo,Integer code){
        CertResult result=new CertResult();
        result.setResult(0);
        switch (InstitutionStatus.getByStatus(code)){
            case VDE:
                result= vdeSearch(webClient,certNo);
                break;
            case TUVR:
                result= tuvRheinlandSearch(webClient,certNo);
                break;
            case TUVSUD:
                result= tuvsudSearch(webClient,certNo);
                break;
            case SAA:
                result= saaSearch(webClient,certNo);
                break;
            case UL:
                result= ulSearch(webClient,certNo);
                break;
            case DEKRA:
                result= dekraKemaSearch(webClient,certNo);
                break;
            case BV:
                break;
            case BS:
                break;
            case ITS_GS:
                break;
            case ITS_ETL:
                break;
            case ITS_S_ENEC:
                break;
            case OTHER:
                break;
                default:
                    break;
        }
        if(result!=null && result.getResult()<0){
            //todo 通知管理员
        }
        return result;
    }


    /**
     * 信任任何站点，实现https页面的正常访问
     *
     */

    private static void trustEveryone() {
        try {
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, new X509TrustManager[] { new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            } }, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
        } catch (Exception e) {
            // e.printStackTrace();
        }
    }

    public static WebClient startAClient(){
        WebClient webClient = new WebClient(BrowserVersion.CHROME);//新建一个模拟谷歌Chrome浏览器的浏览器客户端对象
        webClient.getOptions().setThrowExceptionOnScriptError(false);//当JS执行出错的时候是否抛出异常, 这里选择不需要
        webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);//当HTTP的状态非200时是否抛出异常, 这里选择不需要
        webClient.getOptions().setActiveXNative(false);
        webClient.getOptions().setCssEnabled(false);//是否启用CSS, 因为不需要展现页面, 所以不需要启用
        webClient.getOptions().setJavaScriptEnabled(true); //很重要，启用JS
        webClient.setAjaxController(new NicelyResynchronizingAjaxController());//很重要，设置支持AJAX
        return webClient;
    }


    public static void detroyWebClient(WebClient webClient){
        webClient.close();
    }

}
